package com.media.appmedia.util;

import java.io.File;
import java.io.IOException;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;

/**
 * 下载存储相关操作类 记录下载文件保存位置，检查是否有可用存储设备， 下载文件是否存在，是否有可用存储空间等等。
 */
public class StorageUtil {

	private static final String TAG = "StorageUtil";
	public static final String INSTALL_URL = "application/vnd.android.package-archive";
	/** loading页图片文件名 */
	public static final String LOADING_IMG_FILE_NAME = "loading_img.jpg";

	/** 检测是否有可用的SD卡存储设备 */
	public static boolean getStorageState() {
		final String dirState = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(dirState))
			return true;
		return false;
	}

	/**
	 * 检测当前是否可以下载 判断条件： 1.检测是否有SD卡; 2.检测当前是否有可用网络; 3.检测当前存储设备是否有可用的存储空间
	 * 
	 * @param curApkSize
	 *            当前apk文件大小
	 * @return -1: 当前不可下载 Const.EXTERNAL_DEVICE_FLAG: 下载到外部存储设备
	 */
	/*
	 * public static int isCanDownload(Context ctx, long curApkSize) { //
	 * 检测是否有可用网络 boolean isCanNetWork = PhoneInfoUtils.isNetworkOpen(ctx); if
	 * (!isCanNetWork) { ToastUtils.show(ctx, R.string.none_network_info);
	 * return -1; }
	 */
	// 检测是否有SD卡
	// boolean isStorage = getStorageState();
	/*
	 * if (isStorage) { // 检测SD卡是否有可用的存储空间 boolean isEnoughMemory =
	 * hasEnoughMemory( Const.EXTERNAL_DEVICE_FLAG, curApkSize); if
	 * (isEnoughMemory) { return Const.EXTERNAL_DEVICE_FLAG; } else {
	 * ToastUtils.show(ctx, R.string.none_enough_memory_str); } } else {
	 * ToastUtils.show(ctx, R.string.no_sd_device_info); } return -1; }
	 */

	/**
	 * 安装下载文件包
	 * 
	 * @param context
	 *            活动上下文
	 * @param pkgName
	 *            文件包名
	 * @param saveLocation
	 *            文件存储位置
	 */
	public static void installPkgByPath(Context context, String pkgName,
			int saveLocation) {
		String path = getFilePath(context, pkgName, saveLocation);
		File file = new File(path);
		if (file == null || !file.exists()) {
			MLog.e(TAG, "没有找到要安装的文件:" + path);
			return;
		}
		MLog.d("安装路径：" + path + " ,文件大小：" + file.length());
		if (saveLocation != Const.EXTERNAL_DEVICE_FLAG) {
			try {
				Runtime.getRuntime().exec("chmod 644 " + file);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_VIEW);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setDataAndType(Uri.fromFile(file), INSTALL_URL);
		context.startActivity(intent);
	}

	/**
	 * 获取应用的安装路径
	 * 
	 * @param ctx
	 *            活动上下文
	 * @param pkgName
	 *            应用包名
	 * @param saveLocation
	 *            存储位置
	 * @return
	 */
	public static String getFilePath(Context ctx, String pkgName,
			int saveLocation) {
		String savePath = null;
		if (saveLocation == Const.EXTERNAL_DEVICE_FLAG) {
			savePath = getExternalStoragePath(ctx);
		} else {
			savePath = getInternalStoragePath(ctx);
		}
		savePath = savePath + pkgName + ".apk";
		return savePath;
	}

	/**
	 * 打开应用
	 * 
	 * @param ctx
	 *            活动上下文
	 * @param pkgName
	 *            应用包名
	 */
	public static void openApk(Context ctx, String pkgName) {
		Intent intent = new Intent();
		intent = ctx.getPackageManager().getLaunchIntentForPackage(pkgName);
		if (intent != null) {
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			ctx.startActivity(intent);
		} else {
			MLog.e("mylog", "errr: 在打开应用程序时，没有找到对应应用程序!");
		}
	}

	/**
	 * 卸载应用
	 * 
	 * @param ctx
	 *            活动上下文
	 * @param pkgName
	 *            应用包名
	 */
	public static void uninstallApk(Context ctx, String pkgName) {
		Uri packageURI = Uri.parse("package:" + pkgName);
		Intent intent = new Intent(Intent.ACTION_DELETE, packageURI);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		ctx.startActivity(intent);
	}

	/**
	 * 删除文件包
	 * 
	 * @param pkgName
	 *            要删除的文件包名
	 * @param context
	 *            活动上下文
	 * @param saveLocation
	 *            文件存储位置
	 */
	public static boolean removePkgFile(String pkgName, Context context,
			int saveLocation) {
		String path = null;
		if (saveLocation == Const.EXTERNAL_DEVICE_FLAG) {
			path = getExternalStoragePath(context);
		} else {
			path = getInternalStoragePath(context);
		}
		path += pkgName + ".apk";

		File file = new File(path);
		if (file != null && file.exists()) {
			MLog.d(TAG, "删除磁盘中的存储文件:" + pkgName + " ,saveLocation:"
					+ saveLocation);
			return file.delete();
		}
		return false;
	}

	/**
	 * 删除文件
	 * 
	 * @param filePath
	 *            文件完整路径
	 * @param context
	 *            活动上下文
	 * @param saveLocation
	 *            文件存储位置
	 */
	public static boolean removeFile(String filePath) {
		if (StringUtils.isEmpty(filePath)) {
			return false;
		}
		if (!filePath.contains(".")) {
			filePath = filePath + ".jpg";
		}
		File file = new File(filePath);
		if (file != null) {

			if (file.exists()) {
				return file.delete();
			} else {

			}
		}

		return false;
	}

	public static boolean forceDelete(File f) {
		boolean result = false;
		int tryCount = 0;
		while (!result && tryCount++ < 10) {
			System.gc();
			result = f.delete();
		}
		return result;
	}

	public static boolean copyFile(String filePath) {

		File file = new File(filePath);
		if (file != null && file.exists()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 删除文件
	 * 
	 * @param filePath
	 * @return
	 */
	public static File rename(String filePath) {

		if (StringUtils.isEmpty(filePath)) {
			return null;
		}
		File file = new File(filePath);
		File f = null;
		if (file != null && file.exists()) {
			copyFile(filePath);
			f = new File(file.getName() + "1");
			if (f != null && f.exists()) {
				return f;
			}
		}

		return null;
	}

	private static boolean del(File f) {
		if (f != null && f.exists()) {
			return f.delete();
		}
		return false;
	}

	/**
	 * 创建文件下载路径
	 * 
	 * @param pkgName
	 *            文件包名
	 * @param saveLocation
	 *            文件存储位置
	 * @param context
	 *            活动上下文
	 * @return
	 */
	public static File createPkgFile(String pkgName, int saveLocation,
			Context context) {
		String path = null;
		if (saveLocation == Const.EXTERNAL_DEVICE_FLAG) {
			path = getExternalStoragePath(context);
		} else {
			path = getInternalStoragePath(context);
		}
		path += pkgName;
		path += ".apk";
		try {
			File apkfile = new File(path);
			File dir = apkfile.getParentFile();
			if (!dir.exists())
				dir.mkdirs();
			if (!apkfile.exists())
				apkfile.createNewFile();
			return apkfile;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 创建文件下载路径
	 * 
	 * @param filePath
	 *            文件存储路径
	 * @param saveLocation
	 *            文件存储位置
	 * @param context
	 *            活动上下文
	 * @param isDelPreFile
	 *            是否删除之前的文件,重新建立一个空文件
	 * @return
	 */
	public static File createFile(String filePath, Context context,
			boolean isDelPreFile) {
		MLog.d("创建文件存储位置：path=" + filePath);
		try {
			File file = new File(filePath);
			File dir = file.getParentFile();
			if (!dir.exists())
				dir.mkdirs();
			if (!file.exists()) {
				file.createNewFile();
			} else {
				if (isDelPreFile) {
					file.delete();
					file.createNewFile();
				}
			}
			return file;
		} catch (Exception e) {
			MLog.i("StorageUtils", "create file error: " + e.toString());
			return null;
		}
	}

	/**
	 * 将图片重命名，目的是添加文件后缀 刚从server端拿到下载链接时，是不知道图片文件格式,所以需要在下载完成之后进行处理
	 * 
	 * @param file
	 *            下载完毕的文件
	 */
	/** 判断图片文件是否已经添加后缀 */
	private static boolean isAddSuffix(File file) {
		String fileName = file.getName();
		if (fileName.contains(".")) {
			return true;
		}
		return false;
	}

	/**
	 * 判断某个下载文件是否在存储目录中
	 * 
	 * @param pkgName
	 *            文件包名
	 * @param context
	 *            活动上下文
	 * @return
	 */
	public static boolean isAppExit(String pkgName, Context context) {
		String path = getExternalStoragePath(context) + pkgName + ".apk";
		File apk = new File(path);
		MLog.d("未下载完毕文件的大小: pkgName=" + pkgName + " ,size=" + apk.length());
		if (apk != null && apk.exists())
			return true;
		return false;
	}

	/**
	 * 检索apk文件在设备中的状态（下载完毕、未下载完毕） 未下载完毕要读取该文件的大小
	 * 
	 * 拿包名检索数据库中对应的记录，有可能多条（SD卡记录和内存记录）,检索完毕后放入到集合中
	 * 判断当前是否有SD卡,如果有检测SD卡中是否相应文件,有的话返回该文件.
	 * 如果没有SD卡，或者在SD卡中没有找到该文件，则检测内存，看内存中是否有该文件。
	 * 
	 * @param ownerID
	 *            持有者ID
	 * @param fileID
	 *            文件ID
	 * @return
	 */
	/*
	 * public static FileBean getAppInDevice(Context context, String ownerID,
	 * String fileID) { int location = -1; if (StorageUtil.getStorageState()) {
	 * location = Const.EXTERNAL_DEVICE_FLAG; } else { // 无SD卡,直接检测内存 location =
	 * Const.INTERNAL_DEVICE_FLAG; }
	 * 
	 * FileBean appBean = getAppInDb(context, ownerID, fileID, location); if
	 * (appBean != null) { File file = new File(appBean.getSavePath()); if (file
	 * != null) appBean = getDeviceFile(context, file, appBean); // else //
	 * 当用户手动删除了本地图片，但是库中的记录还在，这时该应用就处于”下载“状态 //
	 * appBean.setResult(Result.DOWNLOAD); } return appBean; }
	 */

	/**
	 * 模糊查询匹配对应文件 根据文件ID来进行匹配，因为当前文件夹内有可能有无后缀和有后缀的文件
	 * 
	 * @param fileId
	 *            文件ID
	 * @return 根据ID检索出的文件
	 */
	// public static File fuzzySearchFileById(Context ctx, String fileId) {
	// String storagePath = null;
	// if (getStorageState()) {
	// storagePath = getExternalStoragePath(ctx);
	// } else {
	// storagePath = getInternalStoragePath(ctx);
	// }
	//
	// File file = new File(storagePath);
	// File files[] = file.listFiles();
	// if (files != null) {
	// for (File f : files) {
	// String fileName = f.getName();
	// if (ImgTool.isImgFile(f)) {
	// if (fileName.startsWith(fileId))
	// return f;
	// }
	// }
	// }
	// return null;
	// }

	/** 获取设备上相应文件 */
	/*
	 * private static FileBean getDeviceFile(Context context, File file,
	 * FileBean appBean) { // 该应用存在对应磁盘中
	 * appBean.setDownloadedBytes(file.length()); MLog.d("file==" +
	 * file.getPath() + ", 已下载文件大小:" + appBean.getDownloadedBytes() +
	 * " , 文件总大小：" + appBean.getApkBytes() + " ,文件大小=" + file.length()); if
	 * (appBean.isDlSuccess()) { appBean.setStatus(Status.FINISHED);
	 * appBean.setResult(Result.SUCCESS); MLog.d(appBean.getFileID() +
	 * "文件下载完成"); } else if (appBean.getDownloadedBytes() >
	 * appBean.getApkBytes()) { // 说明磁盘中的文件时损坏文件
	 * MLog.d("删除磁盘中的损坏文件 downloadBytes=" + appBean.getDownloadedBytes() +
	 * " ,apkBytes=" + appBean.getApkBytes());
	 * StorageUtil.removePkgFile(appBean.getFileID(), context,
	 * appBean.getSaveLocation()); appBean.setResult(Result.DOWNLOAD); } else {
	 * appBean.setStatus(Status.FINISHED); appBean.setResult(Result.PAUSE);
	 * MLog.d(appBean.getFileID() + "文件处于暂停状态"); } return appBean; }
	 */
	/**
	 * 获取某文件记录
	 * 
	 * @param context
	 * @param fileID
	 *            文件ID
	 * @param saveLocation
	 *            文件所在位置
	 * @return
	 */
	/*
	 * public static FileBean getAppInDb(Context context, String ownerID, String
	 * fileID, int saveLocation) { List<FileBean> dbApps =
	 * DownloadTaskMgr.getInstance().getDBDlRecord( context, ownerID, fileID);
	 * int size = dbApps.size(); FileBean dbBean = null; for (int i = 0; i <
	 * size; i++) { dbBean = dbApps.get(i); if
	 * (fileID.equals(dbBean.getFileID()) &&
	 * ownerID.equals(dbBean.getOwnerID())) { return dbBean; } } return null; }
	 */

	/**
	 * 判断某个文件包是否安装
	 * 
	 * @param pkgName
	 *            文件包名
	 * @param context
	 *            活动上下文
	 * @return
	 */
	public static boolean isAppInstall(String pkgName, Context context) {
		PackageInfo packageInfo;
		try {
			packageInfo = context.getPackageManager()
					.getPackageInfo(pkgName, 0);
		} catch (NameNotFoundException e) {
			return false;
		}
		if (packageInfo == null)
			return false;
		else
			return true;
	}

	/** 获取loading页存储位置 */
	public static String getLoadingImgSavePath(Context ctx) {
		return getInternalStoragePath(ctx) + "loadingimg" + File.separator
				+ LOADING_IMG_FILE_NAME;
	}

	/**
	 * arm的外表存储路径
	 * 
	 * @param ctx
	 * @param id
	 * @return
	 */
	public static String getMp3SavePath(Context ctx, String id) {
		return getSavePath(ctx) + File.separator + id + ".amr";

	}

	public static String getSavePath(Context ctx) {
		return Environment.getExternalStorageDirectory().getAbsolutePath()
				+ File.separator + "Android" + File.separator + "data"
				+ File.separator + ctx.getPackageName() + File.separator
				+ "files" + File.separator + "arm";

	}

	/** 获取下载文件外部设备存储路径 */
	public static String getExternalStoragePath(Context context) {
		return Environment.getExternalStorageDirectory().getAbsolutePath()
				+ File.separator + "Android" + File.separator + "data"
				+ File.separator + context.getPackageName() + File.separator
				+ "files" + File.separator + "imgs" + File.separator;
	}

	public static String getLargeImagePath(Context ctx) {
		final String DIR_NAME = "LargeImage";
		String filePath = "";
		if (getStorageState()) {// 有SD卡
			File dir = new File(
					Environment
							.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
					DIR_NAME);
			if (!dir.exists()) {
				dir.mkdir();
			}
			filePath = dir.getAbsolutePath() + File.separator;

		}
		return filePath;
	}

	/** 获取下载文件内部设备（内存）存储路径 */
	public static String getInternalStoragePath(Context context) {
		return context.getFilesDir().getAbsolutePath() + File.separator;
	}

	/**
	 * 获取手机可用的存储空间
	 * 
	 * @param flag
	 *            EXTERNAL_DEVICE_FLAG: 外部存储设备 INTERNAL_DEVICE_FLAG:内部存储设备
	 * @return 单位 M
	 */
	public static float getMemorySize(int flag) {
		File path = null;
		if (flag == Const.EXTERNAL_DEVICE_FLAG) {
			path = Environment.getExternalStorageDirectory();
		} else {
			path = Environment.getRootDirectory();
		}
		StatFs stat = new StatFs(path.getPath());
		@SuppressWarnings("deprecation")
		long blockSize = stat.getBlockSize();
		@SuppressWarnings("deprecation")
		long availableBlocks = stat.getAvailableBlocks();
		return (availableBlocks * blockSize) * 1.0f / (1024 * 1024);
	}

	/**
	 * 是否有可用的下载存储空间
	 * 
	 * @param flag
	 *            下载位置
	 * @param sizeMb
	 *            所有正在下载的文件总大小
	 * @return true 可下载 false 不可下载
	 */
	public static boolean isAvaiableSpace(int flag, float sizeMb) {
		float availableSpare = getMemorySize(flag);
		if (availableSpare > sizeMb)
			return true;
		return false;
	}

	/**
	 * 检测是否有可用的存储空间
	 * 
	 * @param flag
	 *            下载位置
	 * @param apkSize
	 *            要下载的文件大小
	 */
	/*
	 * private static boolean hasEnoughMemory(int flag, long apkSize) { //
	 * 获取下载任务中所有apk所占空间大小 float allSize =
	 * DownloadTaskMgr.getInstance().getAllDlAppMemory(); // 获取当前要下载的apk大小 float
	 * curApkSize = (float) (apkSize * 1.0 / (1024 * 1024 * 1.0)); allSize +=
	 * curApkSize; return isAvaiableSpace(flag, allSize); }
	 */

	/**
	 * 获取应用当前状态
	 * 
	 * @param context
	 * @param pkgName
	 *            应用包名
	 * @return action 应用状态
	 */
	/*
	 * public static Action getAppState(Context context, String pkgName) {
	 * Action action = Action.DOWNLOAD;
	 * 
	 * if (AppUpdateMgr.getInstance().isUpdate(pkgName)) { action =
	 * Action.UPDATE; } else if (isAppInstall(pkgName, context)) { action =
	 * Action.OPEN; } // TODO 初始进入某页面时，获取当前ACTION return action; }
	 */

	/**
	 * 获取磁盘目录下的apk数据集合 下载的应用按下载时间排序，最近的在前面
	 */
	/*
	 * public static ArrayList<FileBean> getDownloadedApps(String ownerID,
	 * Context ctx) { ArrayList<FileBean> downloadList = new
	 * ArrayList<FileBean>();
	 * 
	 * FileBean app; // 获取数据库中的记录 ArrayList<FileBean> dbAppList =
	 * DownloadTaskMgr.getInstance() .getDBRecord(ownerID, ctx); if (dbAppList
	 * == null || dbAppList.size() <= 0) return downloadList;
	 * 
	 * int size = dbAppList.size(); FileBean temp = null; String path = null;
	 * for (int i = 0; i < size; i++) { temp = dbAppList.get(i); if (temp ==
	 * null) continue; boolean isInDownLoading = DownloadTaskMgr.getInstance()
	 * .isInDownload(temp.getFileID()); if (isInDownLoading) { continue; } path
	 * = temp.getSavePath(); MLog.d("path============" + path); app =
	 * getDeviceFile(ctx, new File(path), temp); MLog.d("app==================="
	 * + app.toString() + " , isSuccess=" + app.isDlSuccess());
	 * downloadList.add(app); } return downloadList; }
	 */

	/*
	 * public static ArrayList<FileBean> sorList(ArrayList<FileBean>
	 * downloadList) { Comparator<FileBean> comparator = new
	 * Comparator<FileBean>() {
	 * 
	 * @Override public int compare(FileBean app1, FileBean app2) { if (app2 !=
	 * null && app1 != null) return app2.getFileCreateData().compareTo(
	 * app1.getFileCreateData()); else return 0; } };
	 * Collections.sort(downloadList, comparator); return downloadList; }
	 * 
	 * private static FileBean getAppInDB(ArrayList<FileBean> dbAppList, String
	 * pkgName) { int size = dbAppList.size(); FileBean temp = null; for (int i
	 * = 0; i < size; i++) { temp = dbAppList.get(i); if (temp == null)
	 * continue; if (pkgName.equals(temp.getFileID())) return temp; } return
	 * null; }
	 */

	/** 检测文件是否存在 */
	private static boolean isExistFile(File file) {
		if (file != null && file.exists())
			return true;
		else
			return false;
	}

	/**
	 * 检测文件是否存在
	 * 
	 * @param filePath
	 *            文件存储位置
	 * @return true: 存在 false: 不存在
	 */
	public static boolean isFileExist(String filePath) {
		File file = new File(filePath);
		boolean flag = isExistFile(file);
		return flag;
	}

	/**
	 * 获取发布报道和发布直播拍照保存路径
	 * 
	 * @return 保存拍照后的图片文件
	 * @note 需要检查返回值是否为空，为空的时sd卡不可用
	 */
	public static File getDcimDir() {
		final String DIR_NAME = "TUKU";
		if (getStorageState()) {// 有SD卡
			File dir = new File(
					Environment
							.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
					DIR_NAME);
			if (dir.exists() || dir.mkdirs()) {
				return dir;
			}
		}
		return null;
	}

}
